package utils;


import messagetype.*;
import java.io.*;

//消息装包，解包
/**
 * @author Administrator
 */
public class MsgTool {

    private MsgTool() {
    }    //工具类不允许创建对象

    public static MsHead parseMsg(byte[] data) throws IOException {
        ByteArrayInputStream bin = new ByteArrayInputStream(data);
        DataInputStream din = new DataInputStream(bin);
        int len = 4 + data.length;

        byte type = din.readByte();
        switch (type) {
            case ByteType.REGISTER: {
                String jsonStr = new String(data).trim();
                return new RegMsg(len, type, jsonStr);
            } case ByteType.LOGIN_MESSAGE: {
                String jsonStr = new String(data).trim();
                return new LoginMsg(len, type, jsonStr);
            } case ByteType.CHAT_MESSAGE: {
                String message = new String(data).trim();
                return new ChatMsg(len, type, message);
            } case ByteType.SAVE_IMAGE_MESSAGE: {
                String user = new String(data).trim();
                return new FileMsg(5, type, user);
            } case ByteType.REGISTER_RES_MESSAGE: {
                byte state = din.readByte();
                String jsonStr = new String(data).trim();
                return new RegResMsg(len, type, state, jsonStr);
            } case ByteType.LOGIN_RES_MESSAGE: {
                byte state = din.readByte();
                String jsonStr = new String(data).trim();
                return new LoginResMsg(len, type, state, jsonStr);
            } case ByteType.FIND_USER_MESSAGE: {
                int flag = din.readInt();
                String str = new String(data).trim();
                return new FindMsg(flag,len, type, str);
            } case ByteType.FIND_IMAGE_MESSAGE: {
                String account = new String(data).trim();
                return new FindImageMsg(len, type, account);
            } case ByteType.ADD_FRIEND_MESSAGE:{
                String userInformation = new String(data).trim();
                return new AddFriendMsg(len,type,userInformation);
            } case ByteType.FIND_FRIEND_RES_LIST_MESSAGE:{
                String userInformation = new String(data).trim();
                return new FindResList(len,type,userInformation);
            } case ByteType.ADD_FRIEND_RES_MESSAGE:{
                byte state = din.readByte();
                String userInformation = new String(data).trim();
                return new AddFriendResMsg(len,type,state,userInformation);
            } case ByteType.FRIEND_MESSAGE_LIST:{
                String msgList = new String(data).trim();
                return new FriendMsgList(len,type,msgList);
            } case ByteType.DELETE_FRIEND_MESSAGE:{
                String information = new String(data).trim();
                return new DeleteFriendMsg(len,type,information);
            } case ByteType.BUILD_GROUP_MESSAGE:{
                String groupInformation = new String(data).trim();
                return new CreateGroupMsg(len,type,groupInformation);
            } case ByteType.ADD_USER_TO_GROUP_MESSAGE:{
                String information = new String(data).trim();
                return new AddUserToGroupMsg(len,type,information);
            } case ByteType.ADD_USER_TO_GROUP_RES_MESSAGE:{
                String group = new String(data).trim();
                return new AddUserToGroupResMsg(len,type,group);
            } case ByteType.ALL_CHAT_MESSAGE:{
                String information = new String(data).trim();
                return new TogetherChatMsg(len,type,information);
            } case ByteType.GROUP_MESSAGE_LIST: {
                String messageList = new String(data).trim();
                return new GroupMsgList(len, type, messageList);
            } case ByteType.EXIT_GROUP_MESSAGE:{
                String groupInformation = new String(data).trim();
                return new ExitGroupMsg(len,type,groupInformation);
            } case ByteType.UPDATE_LIST_MESSAGE:{
                int flag = din.readInt();
                String information = new String(data).trim();
                return new UpdateListMsg(len,flag,type,information);
            }
            default: return null;
        }
    }

    public static byte[] packMsg(MsHead msg) throws IOException {
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        DataOutputStream doubt = new DataOutputStream(bout);
        writeHead(msg, doubt);
        byte type = msg.getType();
        switch (type) {
            case ByteType.REGISTER:
                RegMsg rm = (RegMsg) msg;
                writeString(rm.getJsonStr(), rm.getJsonStr().length(), doubt);
                return bout.toByteArray();
            case ByteType.LOGIN_MESSAGE:
                LoginMsg lm = (LoginMsg) msg;
                writeString(lm.getJsonStr(), lm.getJsonStr().length(), doubt);
                return bout.toByteArray();
            case ByteType.CHAT_MESSAGE:
                ChatMsg cm = (ChatMsg) msg;
                writeString(cm.getPrivateMsg(), cm.getPrivateMsg().length(), doubt);
                doubt.flush();
                return bout.toByteArray();
            case ByteType.SAVE_IMAGE_MESSAGE:
                FileMsg fM = (FileMsg) msg;
                writeString(fM.getUser(), fM.getUser().length(), doubt);
                return bout.toByteArray();
            case ByteType.REGISTER_RES_MESSAGE:
                RegResMsg rrm = (RegResMsg) msg;
                doubt.writeByte(rrm.getState());
                writeString(rrm.getJsonStr(), rrm.getJsonStr().length(), doubt);
                return bout.toByteArray();
            case ByteType.LOGIN_RES_MESSAGE:
                LoginResMsg lrm = (LoginResMsg) msg;
                doubt.writeByte(lrm.getState());
                writeString(lrm.getJsonStr(), lrm.getJsonStr().length(), doubt);
                return bout.toByteArray();
            case ByteType.FIND_USER_MESSAGE:
                FindMsg fm = (FindMsg) msg;
                doubt.writeInt(fm.getFlag());
                writeString(fm.getInformation(), fm.getInformation().length(), doubt);
                return bout.toByteArray();
            case ByteType.FIND_IMAGE_MESSAGE:
                FindImageMsg fim = (FindImageMsg) msg;
                writeString(fim.getAccountAndImage(), fim.getAccountAndImage().length(), doubt);
                return bout.toByteArray();
            case ByteType.ADD_FRIEND_MESSAGE:
                AddFriendMsg afm = (AddFriendMsg) msg;
                writeString(afm.getUserInformation(), afm.getUserInformation().length(),doubt);
                return bout.toByteArray();
            case ByteType.FIND_FRIEND_RES_LIST_MESSAGE:
                FindResList frl = (FindResList) msg;
                writeString(frl.getUserInformation(),frl.getUserInformation().length(),doubt);
                return bout.toByteArray();
            case ByteType.ADD_FRIEND_RES_MESSAGE:
                AddFriendResMsg arm = (AddFriendResMsg) msg;
                doubt.writeByte(arm.getState());
                writeString(arm.getInformation(),arm.getInformation().length(),doubt);
                return bout.toByteArray();
            case ByteType.FRIEND_MESSAGE_LIST:
                FriendMsgList fml = (FriendMsgList) msg;
                writeString(fml.getMsgList(),fml.getMsgList().length(),doubt);
                return bout.toByteArray();
            case ByteType.DELETE_FRIEND_MESSAGE:
                DeleteFriendMsg dfm = (DeleteFriendMsg) msg;
                writeString(dfm.getInformation(), dfm.getInformation().length(),doubt);
                return bout.toByteArray();
            case ByteType.BUILD_GROUP_MESSAGE:
                CreateGroupMsg cgm = (CreateGroupMsg) msg;
                writeString(cgm.getGroupInformation(),cgm.getGroupInformation().length(),doubt);
                return bout.toByteArray();
            case ByteType.ADD_USER_TO_GROUP_MESSAGE:
                AddUserToGroupMsg au = (AddUserToGroupMsg) msg;
                writeString(au.getInformation(),au.getInformation().length(),doubt);
                return bout.toByteArray();
            case ByteType.ADD_USER_TO_GROUP_RES_MESSAGE:
                AddUserToGroupResMsg autg = (AddUserToGroupResMsg) msg;
                writeString(autg.getInformation(),autg.getInformation().length(),doubt);
                return bout.toByteArray();
            case ByteType.ALL_CHAT_MESSAGE:
                TogetherChatMsg tt = (TogetherChatMsg) msg;
                writeString(tt.getInformation(),tt.getInformation().length(),doubt);
                return bout.toByteArray();
            case ByteType.GROUP_MESSAGE_LIST:
                GroupMsgList gm = (GroupMsgList) msg;
                writeString(gm.getInformation(),gm.getInformation().length(),doubt);
                return bout.toByteArray();
            case ByteType.EXIT_GROUP_MESSAGE:
                ExitGroupMsg egm = (ExitGroupMsg) msg;
                writeString(egm.getGroupInformation(),egm.getGroupInformation().length(),doubt);
                return bout.toByteArray();
            case ByteType.UPDATE_LIST_MESSAGE:
                UpdateListMsg ulm = (UpdateListMsg) msg;
                doubt.writeInt(ulm.getState());
                writeString(ulm.getInformation(),ulm.getInformation().length(),doubt);
                return bout.toByteArray();
            default:
                return null;
        }
    }

    private static void writeHead(MsHead msg, DataOutputStream doubt) throws IOException {
        doubt.writeInt(msg.getLen());
        doubt.writeByte(msg.getType());
    }

    private static void writeString(String msg, int len, DataOutputStream doubt) throws IOException {
        byte[] data = msg.getBytes();
        doubt.write(data);
    }

    public static MsHead readMsgHead(DataInputStream din) throws IOException {
        int len = din.readInt();
        byte[] bytes = new byte[len - 4];
        din.readFully(bytes);
        MsHead msg = MsgTool.parseMsg(bytes);
        return msg;
    }
}
